/**
 * Author：LSP
 * Date：2020-12-11
 */

//------------------------------------------------
// 脚本名字
const name = Script.name()
// 文件
const fm = FileManager.local()
//------------------------------------------------
// 选定热榜
let hotArr = [
    "https://tophub.today/n/KqndgxeLl9", // 微博
    "https://tophub.today/n/mproPpoq6O", // 知乎
]

//------------------------------------------------

// 配置
const widgetConfigs = {
    // TopHub在PC端登录后获取cookie放进来
    cookies: "", 
    // 内容上边距
    contentTopPadding: 10,
    // 内容左边距
    contentLeftPadding: 14,
    // 内容下边距
    contentBottomPadding: 10,
    // 内容右边距
    contentRightPadding: 0,
    // 自动匹配模式，该模式下榜单标题大小写死，榜单条数自动调整
    autoMode: true,
    // 大组件可以显示多少行
    bigRowMaxCount: 7,
    // 中组件可以显示多少行
    mediumRowMaxCount: 4,
    // 热榜显示条数
    limit: 6,
    // 榜单logo大小
    logoSize: 18,
    // logo圆角
    logoRadius: 4,
    // 热搜榜来源标题字体
    sourceTitleFont: Font.systemFont(15),
    // 热搜榜来源标题颜色，后面的数字表示透明度
    sourceTitleColor: new Color("FFFFFF", 0.8),
    // 榜单标题序号字体
    titleNumFont: Font.italicSystemFont(15),
    // 榜单标题字体
    titleFont: Font.systemFont(13),
    // 榜单标题颜色，后面的数字表示透明度
    titleColor: new Color("FFFFFF", 0.7),
    // 前三名榜单数字颜色
    frontTitleColor: new Color("EA4041", 0.8),
    // 榜单标题之间的间距
    titleMargin: 10,
    // 热榜标题最多显示多少行，默认1行，超出部分省略号
    titleLineLimit: 1,
    // 组件背景色
    widgetBackgroundColor: new Color("000000", 0.9),
    // 组件是否使用图片作为背景
    widgetUsePicBackground: true,
    // 组件图片背景缓存
    widgetPicBgCacheKey: "picBgCache",
    // 组件使用背景图片时候，在图片上层的蒙版颜色
    widgetShadowPicBgColor: new Color("000000", 0.5),
    // 热榜轮播索引key
    hot_name_index_key: "hot_index_key",
    // 数据缓存名
    dataCacheKey: "topHub",
    // 微博热榜打开方式：0-》浏览器，1-》微博客户端，2-》微博国际版客户端，3-》vvebo客户端
    weiboOpenType: 3,
}
//------------------------------------------------



//------------------------------------------------
// logo缓存目录
let logo_cache_path = fm.joinPath(fm.documentsDirectory(), `lsp-logo-cache-${name}`)
// 组件图片背景缓存目录
let bg_pic_cache_path = fm.joinPath(fm.documentsDirectory(), `lsp-bg-pic-cache-${name}`)
//------------------------------------------------



//------------------------------------------------
// 热榜索引
const hot_size = hotArr.length
let hot_index = 0
const hot_name_index_key = widgetConfigs.hot_name_index_key
if (Keychain.contains(hot_name_index_key)) {
    const last = Keychain.get(hot_name_index_key)
    hot_index = parseInt(last)
}
if (hot_index >= hot_size) {
    hot_index = 0
}
//------------------------------------------------



//------------------------------------------------
// 绘制图片阴影浮层
async function loadShadowColor2Image(img, shadowColor) {
    let drawContext = new DrawContext()
    drawContext.size = img.size
    // 把图片画上去
    drawContext.drawImageInRect(img, new Rect(0, 0, img.size['width'], img.size['height']))
    // 填充蒙版颜色
    drawContext.setFillColor(shadowColor)
    // 填充
    drawContext.fillRect(new Rect(0, 0, img.size['width'], img.size['height']))
    return await drawContext.getImage()
}
//------------------------------------------------




//////////////////////////////////////////////////////////////
/**
 * 请求初始化
 */
const request = new Request(hotArr[hot_index])
const defaultHeaders = {
    "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.67 Safari/537.36",
    "cookie": widgetConfigs.cookies,
}
request.method = 'GET'
request.headers = defaultHeaders
// 热榜数据
let response = undefined
try {
    const html = await request.loadString()
    let webview = new WebView()
    await webview.loadHTML(html)
    // 通过dom操作把HTML里面的热榜内容提取出来
    var getData = `
    function getData() {
        // 获取榜单标题
        hotTitle = document.querySelector('.Xc-ec-L').innerText
        // 获取logo链接
            logoImgHtml = document.querySelector('#tabbed-header-panel div').innerHTML;
        // 提取src的正则表达式
        logoPattern = /<img.*?src{1}=['"]([^'"]+)['"]+/g;
        // 提取logo链接
        logoUrl = logoPattern.exec(logoImgHtml)[1]
        
        // 链接
        linkArr = []
        // 标题
        titleArr = []
        // 所有节点
        allItemNodeList = document.querySelectorAll('.al')
        for(let node of allItemNodeList) {
            // 链接
            node.innerHTML.replace(/<a [^>]*href=['"]([^'"]+)[^>]*/gi, function(match, link){
                linkArr.push(link)
            });
            // 标题
            titleArr.push(node.innerText)
        }

        return {hotTitle: hotTitle, logoUrl: logoUrl, linkArr: linkArr, titleArr: titleArr}
    }
    
    getData()
    `
    // 热榜数据
    response = await webview.evaluateJavaScript(getData, false)
    // 缓存请求数据
    Keychain.set(widgetConfigs.dataCacheKey, JSON.stringify(response))
    // 保存轮播索引
    Keychain.set(hot_name_index_key, `${hot_index + 1}`)
} catch (error) {
    if (Keychain.contains(widgetConfigs.dataCacheKey)) {
        response = JSON.parse(Keychain.get(widgetConfigs.dataCacheKey))
    }
}



//////////////////////////////////////////////////////////////
/**
 * 数据接入小组件
 */
const widget = new ListWidget()
widget.setPadding(widgetConfigs.contentTopPadding, widgetConfigs.contentLeftPadding, widgetConfigs.contentBottomPadding, widgetConfigs.contentRightPadding)
// 热榜标题stack
const sourceStack = widget.addStack()
sourceStack.size = new Size(300, 30)
sourceStack.layoutHorizontally()
sourceStack.centerAlignContent()
// logo链接
request.url = response.logoUrl
let logoImg = undefined
try {
    logoImg = await request.loadImage()
    // logo写入缓存
    fm.writeImage(logo_cache_path, logoImg)
} catch (error) {
    // 读取上次logo的缓存
    logoImg = fm.readImage(logo_cache_path)
}
let logoWidgetImg = sourceStack.addImage(logoImg)
logoWidgetImg.imageSize = new Size(widgetConfigs.logoSize, widgetConfigs.logoSize)
// 圆角
logoWidgetImg.cornerRadius = widgetConfigs.logoRadius
// logo、标题间距
sourceStack.addSpacer(6)
// 热榜标题
const hotName = response.hotTitle
let sourceTitleWidgetText = sourceStack.addText(hotName)
sourceTitleWidgetText.font = widgetConfigs.sourceTitleFont
sourceTitleWidgetText.textColor = widgetConfigs.sourceTitleColor
// 靠左
sourceStack.addSpacer()
// 热搜来源与榜单之间距离
// 标题
const titleArr = response.titleArr
// 榜单链接
const linkArr = response.linkArr
// 榜单条数
let limitCount = widgetConfigs.limit
// 序号字体
let titleNumFont = widgetConfigs.titleNumFont
// 榜单字体
let titleFont = widgetConfigs.titleFont
// 每条榜单显示的行数
titleLineLimit = widgetConfigs.titleLineLimit

// 自动匹配模式
if (widgetConfigs.autoMode) {
    // 写死字号
    titleNumFont = Font.italicSystemFont(15)
    titleFont = Font.systemFont(13)
    titleLineLimit = 10

    // 小组件尺寸
    const widgetSize = config.widgetFamily
    // 最多行数
    let maxRowCount = widgetConfigs.bigRowMaxCount
    if (widgetSize == "medium") {
        maxRowCount = widgetConfigs.mediumRowMaxCount
        // 越界判断
        if (maxRowCount > titleArr.length) {
            maxRowCount = titleArr.length
        }
    } else {
        const lineMax = 10
        let tempRowCount = 0
        
        // 越界判断
        if (maxRowCount > titleArr.length) {
            maxRowCount = titleArr.length
        }
        for (let index = 0; index < maxRowCount; index++) {
            const titleElement = titleArr[index];
            const rowCount = Math.floor(titleElement.length / 20)
            tempRowCount = tempRowCount + rowCount
        }
        if (tempRowCount < lineMax) {
            maxRowCount = lineMax
        }
    }
    // 确定行数
    limitCount = maxRowCount
}


for (let index = 0; index < limitCount; index++) {
    // 标题
    const title = titleArr[index];
    // 链接
    let linkElement = linkArr[index];
    if (widgetConfigs.autoMode) {
        widget.addSpacer()
    } else {
        widget.addSpacer(widgetConfigs.titleMargin)
    }
    // 热搜标题
    const titleStack = widget.addStack()
    if (hotName.search("微博") != -1) {
        const weiboOpenType = widgetConfigs.weiboOpenType
        if (weiboOpenType == 1) {
            // 微博客户端
            linkElement = 'sinaweibo://searchall?q=' + encodeURIComponent(`#${title}#`)
        } else if (weiboOpenType == 2) {
            weibointernational
            // 微博国际版客户端
            linkElement = 'weibointernational://search?q=' + encodeURIComponent(`#${title}#`)
        } else if (weiboOpenType == 3) {
            // vvebo微博客户端
            linkElement = 'vvebo://search?q=' + encodeURIComponent(`#${title}#`)
        }
    }
    titleStack.url = linkElement
    titleStack.layoutHorizontally()
    const titleNumWidgetText = titleStack.addText(`${index + 1}`)
    titleNumWidgetText.font = widgetConfigs.titleNumFont
    if (index < 3) {
        titleNumWidgetText.textColor = widgetConfigs.frontTitleColor
    } else {
        titleNumWidgetText.textColor = widgetConfigs.titleColor
    }
    titleStack.addSpacer(8)
    const titleWidgetText = titleStack.addText(`${title}`)
    titleWidgetText.font = widgetConfigs.titleFont
    titleWidgetText.textColor = widgetConfigs.titleColor
    titleWidgetText.lineLimit = titleLineLimit
    // 靠左
    titleStack.addSpacer()
}
// 使用颜色还是图片
if (widgetConfigs.widgetUsePicBackground) {
    // 图片背景
    let widgetBgImg = undefined
    if (config.runsInApp) {
        // 图库选择图片
        widgetBgImg = await Photos.fromLibrary()
        // 图片背景写入缓存
        fm.writeImage(bg_pic_cache_path, widgetBgImg)
    } else {
        // 缓存中读取图片
        widgetBgImg = fm.readImage(bg_pic_cache_path)
    }
    // 设置背景图
    widget.backgroundImage = await loadShadowColor2Image(widgetBgImg, widgetConfigs.widgetShadowPicBgColor)
} else {
    // 组件背景颜色
    widget.backgroundColor = widgetConfigs.widgetBackgroundColor
}
widget.addSpacer()
widget.refreshAfterDate = new Date(30 * 1000)
// 完成进行预览
widget.presentLarge()
Script.setWidget(widget)
Script.complete()
